package gaej.example.contact.client;

import java.util.List;
import java.util.ArrayList;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

public class MuziekstukGUI {
    /* Constants. */
    private static final String LISTING_ROOT_PANEL = "guiListing";
    private static final String FORM_ROOT_PANEL = "guiForm";
    private static final String STATUS_ROOT_PANEL = "guiStatus";
    private static final String TOOL_BAR_ROOT_PANEL = "guiToolBar";
    private static final int EDIT_LINK = 2;
    private static final int REMOVE_LINK = 3;

    /* GUI Widgets */
    protected Button addButton;
    protected Button updateButton;
    protected Button addNewButton;
    protected ListBox componistNrField;
    protected TextBox titelField;
    protected TextBox genreField;

    protected ArrayList<TextBox> bezettingInstrumentFields;
    protected ArrayList<TextBox> bezettingAantalFields;

    protected Label status;
    protected Grid listGrid;
    protected Grid formGrid;
    protected Grid stukGrid;
    
    /* Data model */
    private List<Componist> componisten;

    private List<Muziekstuk> muziekstukken;
    private Muziekstuk currentMuziekstuk;
    private List<Bezetting> currentMuziekstukBezetting;
    
    protected MuziekstukDelegate muziekstukService;
        
    public void init() {
        addButton = new Button("Add muziekstuk");
        addNewButton = new Button("Add new muziekstuk");
        updateButton = new Button("Update muziekstuk");
        componistNrField = new ListBox();
        titelField = new TextBox();
        genreField = new TextBox();
        
        bezettingInstrumentFields = new ArrayList<TextBox>();
        bezettingAantalFields = new ArrayList<TextBox>();
        currentMuziekstukBezetting = new ArrayList<Bezetting>();
        
        status = new Label();
        listGrid = new Grid(2,5);
        stukGrid = new Grid(2,3);

        buildForm();
        placeWidgets();
    }
    
    private void buildForm() {
        formGrid = new Grid(5,3);
        formGrid.setVisible(false);
        
        formGrid.setWidget(0, 0, new Label("Componist"));
        formGrid.setWidget(0, 1, componistNrField);

        formGrid.setWidget(1, 0, new Label("Titel"));
        formGrid.setWidget(1, 1, titelField);

        formGrid.setWidget(2, 0, new Label("Genre"));
        formGrid.setWidget(2, 1, genreField);

        formGrid.setWidget(3, 0, new Label("Bezetting"));
        formGrid.setWidget(3, 1, stukGrid);
        
        formGrid.setWidget(4, 0, updateButton);
        formGrid.setWidget(4, 1, addButton);
        
    }

    private void placeWidgets() {
        RootPanel.get(LISTING_ROOT_PANEL).add(listGrid);
        RootPanel.get(FORM_ROOT_PANEL).add(formGrid);
        RootPanel.get(STATUS_ROOT_PANEL).add(status);
        RootPanel.get(TOOL_BAR_ROOT_PANEL).add(addNewButton);
    }

    public void hideGui() {
    	formGrid.setVisible(false);
    	listGrid.setVisible(false);
    	status.setVisible(false);
    	addNewButton.setVisible(false);
    }

    
    private void loadForm(Muziekstuk muziekstuk) {
 	
        this.formGrid.setVisible(true);
        currentMuziekstuk = muziekstuk;
        //this.componistNrField.setText(muziekstuk.getComponistNr().toString());
        this.componistNrField.clear();
        int index = 0;
        int selected = 0;
        for (Componist componist : componisten) {
        	this.componistNrField.addItem(componist.getPersoon().getNaam());
        	if (muziekstuk.getComponistNr().longValue() == 
        			componist.getComponistNr().longValue()) {
        		selected = index;
        		//this.componistNrField.setSelectedIndex(index);
        	}
        	index++;
        }
        this.componistNrField.setSelectedIndex(selected);
        this.titelField.setText(muziekstuk.getTitel());
        this.genreField.setText(muziekstuk.getGenre());
    }


    private void copyFieldDateToMuziekstuk() {
    	int selected = this.componistNrField.getSelectedIndex();

    	Long componistNr = 0L;
        if (componisten.size() > selected) {
        	componistNr = componisten.get(selected).getComponistNr();
        }
        
        //currentMuziekstuk.setComponistNr(Long.parseLong(componistNrField.getText()));
        currentMuziekstuk.setComponistNr(componistNr);
        currentMuziekstuk.setTitel(titelField.getText());
        currentMuziekstuk.setGenre(genreField.getText());
        
        // overnemen van de ingegeven muziekstukbezetting gegevens
        int rows = this.bezettingInstrumentFields.size();
        this.currentMuziekstukBezetting.clear();
        for (int row=0; row<rows; row++) {
        	String instrument = this.bezettingInstrumentFields.get(row).getText().trim();
        	String strAantal = this.bezettingAantalFields.get(row).getText();
        	Long aantal = 0L;
    		try {
    			aantal = Long.parseLong(strAantal);
    		} catch (Exception ex) { }
        	if (!instrument.isEmpty() || aantal == 0) {
	        	Bezetting bezetting = new Bezetting();
	        	bezetting.setInstrument(instrument);
	        	bezetting.setAantal(aantal);
	        	this.currentMuziekstukBezetting.add(bezetting);
        	}
        }
        currentMuziekstuk.setBezetting(this.currentMuziekstukBezetting);

    }

    public void gui_eventListGridClicked(Cell cellClicked) {
         int row = cellClicked.getRowIndex();
         int col = cellClicked.getCellIndex();
        
         Muziekstuk muziekstuk = this.muziekstukken.get(row);
         this.status.setText("Naam was " + muziekstuk.getTitel() + " clicked ");
        
         if (col==EDIT_LINK) {
             this.addNewButton.setVisible(false);
             this.updateButton.setVisible(true);
             this.addButton.setVisible(false);
             
         	 // lijst van Muziekstukbezetting ophalen,
             // asynchroon via de ServiceDelegate
             // deze vult ook de stukGrid-velden !!
         	 muziekstukService.listMuziekstukBezetting(muziekstuk);

             loadForm(muziekstuk);
         } else if (col==REMOVE_LINK) {
        	 if (Window.confirm("Verwijderen muziekstuk ?")) {
        		 this.muziekstukService.removeMuziekstuk(muziekstuk);
        	 }
         }
    }


    public void gui_eventAddButtonClicked() {
        addNewButton.setVisible(true);
        formGrid.setVisible(false);
        copyFieldDateToMuziekstuk();
        this.muziekstukService.addMuziekstuk(currentMuziekstuk);
    }

    public void gui_eventUpdateButtonClicked() {
        addNewButton.setVisible(true);
        formGrid.setVisible(false);
        copyFieldDateToMuziekstuk();
        this.muziekstukService.updateMuziekstuk(currentMuziekstuk);
    }

    public void gui_eventAddNewButtonClicked() {
        this.addNewButton.setVisible(false);
        this.updateButton.setVisible(false);
        this.addButton.setVisible(true);
        Muziekstuk muziekstuk = new Muziekstuk();
        muziekstuk.setComponistNr(0L);
        
        this.currentMuziekstukBezetting.clear();
    	// lijst van Muziekstukbezetting initialiseren 
        // rechtstreeks, wnat het muziekstuk heeft nog geen bezettingsgegevens
        this.service_bezettingListRetrievedFromService(this.currentMuziekstukBezetting);
        
        loadForm(muziekstuk);
    }

    public void service_componistenListRetrievedFromService(List<Componist> result) {
    	this.componisten = result;	
    }

    public void service_bezettingListRetrievedFromService(List<Bezetting> result) {
    	// wordt aangeroepen vanuit muziekstukDelegate bij een bestaand muziekstuk
    	// en rechtstreeks bij een nieuw muziekstuk

    	this.currentMuziekstukBezetting = result;
    	
    	// Grid opnieuw instellen
    	stukGrid.setVisible(true);
        this.stukGrid.clear();
        int rows = 2+this.currentMuziekstukBezetting.size();
        this.stukGrid.resizeRows(rows);
        
        // eventuele oude rommel weghalen
        this.bezettingInstrumentFields.clear();
        this.bezettingAantalFields.clear();

        // extra toevoegregel met titel
        int row = 0;
        this.stukGrid.setWidget(row, 0, new Label("Instrument"));
        this.stukGrid.setWidget(row, 1, new Label("Aantal"));

        // alle regels vullen
        row++;
        for (Bezetting bezetting : this.currentMuziekstukBezetting ) {
        	// instrument invoerveld
        	TextBox instrumentField = new TextBox();
        	instrumentField.setText(bezetting.getInstrument());
        	this.bezettingInstrumentFields.add(instrumentField);
        	// aantal invoerveld
        	TextBox aantalField = new TextBox();
        	aantalField.setText(bezetting.getAantal().toString());
        	this.bezettingAantalFields.add(aantalField);
            this.stukGrid.setWidget(row, 0, instrumentField);
            this.stukGrid.setWidget(row, 1, aantalField);
            row++;
        }
        
        // extra toevoegregel met lege velden
    	TextBox instrumentField = new TextBox();
    	instrumentField.setText("");
    	this.bezettingInstrumentFields.add(instrumentField);
    	TextBox aantalField = new TextBox();
    	aantalField.setText("0");
    	this.bezettingAantalFields.add(aantalField);
        this.stukGrid.setWidget(row, 0, instrumentField);
        this.stukGrid.setWidget(row, 1, aantalField);
        this.stukGrid.setWidget(row, 2, new Label("++"));
   
    }    
    
    public void service_eventListRetrievedFromService(List<Muziekstuk> result) {
        status.setText("Retrieved muziekstuk list");
        status.setVisible(true);

        //formGrid.setVisible(false);
    	listGrid.setVisible(true);
    	status.setVisible(true);
    	addNewButton.setVisible(true);
        
        this.muziekstukken = result;
        this.listGrid.clear();
        this.listGrid.resizeRows(this.muziekstukken.size());
        int row = 0;
        this.addNewButton.setVisible(true);
        
        for (Muziekstuk muziekstuk : result) {
            this.listGrid.setWidget(row, 0, new Label (muziekstuk.getTitel()));
            this.listGrid.setWidget(row, 1, new Label (muziekstuk.getGenre()));
            this.listGrid.setWidget(row, EDIT_LINK, new Hyperlink("Edit", null));
            this.listGrid.setWidget(row, REMOVE_LINK, new Hyperlink("Remove", null));
            row ++;
        }
    }

    public void service_eventAddMuziekstukSuccessful() {
        status.setText("Muziekstuk was successfully added");
        this.muziekstukService.listMuziekstukken();
    }

    public void service_eventUpdateSuccessful() {
        status.setText("Muziekstuk was successfully updated");
        this.muziekstukService.listMuziekstukken();
    }
    public void service_eventRemoveMuziekstukSuccessful() {
        status.setText("Muziekstuk was removed");
        this.muziekstukService.listMuziekstukken();
    }

    public void service_eventUpdateMuziekstukFailed(Throwable caught) {
        status.setText("Update muziekstuk failed");
    }

    public void service_eventAddMuziekstukFailed(Throwable caught) {
        status.setText("Unable to update muziekstuk");
    }

    public void service_eventRemoveMuziekstukFailed(Throwable caught) {
        status.setText("Remove muziekstuk failed");
    }

    public void service_eventListMuziekstukkenFailed(Throwable caught) {
        status.setText("Unable to get muziekstuk list");
    }
    
    public void service_eventListMuziekstukBezettingFailed(Throwable caught) {
        status.setText("Unable to get muziekstukbezetting list");
    }
}
